package com.fingard.util;

import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.BankConfig;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directConfig.TaskTimerSet;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.bankInterface.IFileResolveDifference;
import com.fingard.dsp.bank.reqrespobj.ReqRespHeader;
import com.fingard.dsp.bankset.BankFront;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;

import static com.fingard.text.StringHelper.trimEndFileSp;

/**
 * create Alan
 * date 2019/03/07
 * 外资银行MT文件公共处理方式
 */
public class ForeignBankUtil {
    /**
     * 目录分割符
     */
    private final String SEPARATOR = "/";
    //MT940&MT942
    protected String tag20 = ":20:";
    protected String tag21 = ":21:";
    protected String tag25 = ":25:";
    protected String tag28 = ":28C:";
    protected String tag61 = ":61:";
    protected String tag86 = ":86:";
    //MT940
    protected String tag60F = ":60F:";
    protected String tag60M = ":60M:";
    protected String tag62F = ":62F:";
    protected String tag62M = ":62M:";
    protected String tag64 = ":64:";
    protected String tag65 = ":65:";
    //MT942
    protected String tag34F = ":34F:";
    protected String tag13D = ":13D:";
    protected String tag90D = ":90D:";
    protected String tag90C = ":90C:";

    public BankConfig bankConfig = null;//bankconfig配置信息
    public BankFront bankFront = null;//bankfront配置信息
    public StringBuilder sblog = null;//日志
    public ReqRespHeader header = null;//请求头信息
    public String charset;//编码
    protected String splitFlag = "";//明细分隔符
    protected String startFlag = "";//解析内容起始符号
    protected String endFlag = "";//解析内容终止符号
    String receivePath = "";//下载后未处理文件的存放位置
    String decryptPath = "";//解密之后文件的存放位置
    String successPath = "";//解密成功后原文件的存放位置
    String exceptionPath = "";//解密失败后原文件的存放位置
    String dealedPath = "";//解析后存放文件

    public ForeignBankUtil(BankConfig bankConfig2, BankFront bankFront2, StringBuilder sblog2, String charset2) {
        bankFront = bankFront2;
        bankConfig = bankConfig2;
        sblog = sblog2;
        charset = charset2;
    }

    public ForeignBankUtil(TaskTimerSet timerSet, BankConfig bankConfig2, BankFront bankFront2, StringBuilder sblog2
            , String charset2, String splitFlag2, String startFlag2, String endFlag2) {
        if (timerSet.taskNameList != null) {
            ReqRespHeader tmpHeader = new ReqRespHeader();
            tmpHeader.bankCode = timerSet.bankFront.bankCode;
            tmpHeader.corporation = timerSet.bankFront.corporation;
            tmpHeader.group = timerSet.bankFront.group;
            tmpHeader.transType = "ScheduleTask." + timerSet.taskNameList;
            header = tmpHeader;
        }
        bankFront = bankFront2;
        bankConfig = bankConfig2;
        sblog = sblog2;
        charset = charset2;
        splitFlag = splitFlag2;
        startFlag = startFlag2;
        endFlag = endFlag2;
        //下载后未处理文件的存放位置
        receivePath = StringHelper.trimEndFileSp(bankConfig.getValueAsString("ReceiveFilePath")) + File.separator;
        if (!FileHelper.existFile(receivePath)) {
            FileHelper.mkdir(receivePath);
        }
        //解密之后文件的存放位置
        decryptPath = StringHelper.trimEndFileSp(bankConfig.getValueAsString("DecryptPath")) + File.separator;
        if (!FileHelper.existFile(decryptPath)) {
            FileHelper.mkdir(decryptPath);
        }
        //解密成功后原文件的存放位置
        successPath = StringHelper.trimEndFileSp(bankConfig.getValueAsString("SuccessFilePath")) + File.separator;
        if (!FileHelper.existFile(successPath)) {
            FileHelper.mkdir(successPath);
        }
        //解密失败后原文件的存放位置
        exceptionPath = StringHelper.trimEndFileSp(bankConfig.getValueAsString("ExceptionFilePath")) + File.separator;
        if (!FileHelper.existFile(exceptionPath)) {
            FileHelper.mkdir(exceptionPath);
        }
        //解析后存放文件
        dealedPath = StringHelper.trimEndFileSp(bankConfig.getValueAsString("DealedPath")) + File.separator;
        if (!FileHelper.existFile(dealedPath)) {
            FileHelper.mkdir(dealedPath);
        }
    }

    /**
     * MT文件下载并解析
     *
     * @param object base类
     */
    public void downloadFiles(Object object, String sftpName) {
        try {
            synchronized (object) {
                //下载sftp文件
                downloadFileBySftp(sftpName, receivePath);
                //文件解密
                if ("MUFG01".equals(bankFront.bankCode) || "BNPP02".equals(bankFront.bankCode)) {
                    //不用解签
                    decryptFileIsGpg(receivePath, decryptPath, successPath, false);
                } else {
                    //需要解签
                    decryptFileIsGpg(receivePath, decryptPath, successPath, true);
                }
                //获取待解析的文件集合
                List<String> fileNameList = decryptFileName(decryptPath);
                //解析文件
                analysisFile(fileNameList, decryptPath, successPath, exceptionPath);
            }
        } catch (Exception e) {
            e.printStackTrace();
            WriteBankLogLn("sftp服务器下载文件异常：" + e);
        }
    }

    /**
     * sftp下载文件
     */
    public void downloadFileBySftp(String sftpName, String receiveFile) {
        try {
            String sftpType = bankConfig.getValueAsString("sftpType");
            if (StringHelper.hasAnyChar(sftpType)) {
                List<String> fileList = new ArrayList<String>();
                if (!FileHelper.existFile(receiveFile)) {
                    FileHelper.mkdir(receiveFile);
                }
                FtpSet ftpSet = bankFront.getFtpSet(sftpName);
                ftpSet.downDir = StringHelper.trimEndFileSp(ftpSet.downDir) + SEPARATOR;
                ftpSet.upDir = StringHelper.trimEndFileSp(ftpSet.upDir) + SEPARATOR;
                SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
                FtpReceiver receiver = null;
                WriteBankLogLn("***********连接SFTP服务器开始***********");
                String sshKeyPassword = bankConfig.getValueAsString("privateKeyPaswd");
                sshKeyPassword = StringHelper.hasAnyChar(sshKeyPassword) ? sshKeyPassword : ftpSet.sshKeyPassword;
                WriteBankLogLn("SFTP服务器连接中，请稍后...");
                if("true".equals(bankConfig.getValueAsString("downFileDelFlag")) && "SMBC01".equals(bankFront.bankCode)){
                    /*三井住友项目sftp服务器文件下载后不会自动删除，为了保证我们不去做sftp文件删除操作
                    ，在此模式下，根据配置的天数只下载前n天的文件，减少下载文件数，减少性能的损耗
                    ，对于我们下载重复的文件，在解析时有防重操作 */
                    int downloadDays=bankConfig.getValueAsInt("downloadDays",1,"true");
                    if(downloadDays<0){
                        downloadDays=1;
                    }
                    receiver = sftpPortClient.downloadFileBySftp("", receiveFile, Integer.parseInt(sftpType), sshKeyPassword, downloadDays);
                }else {
                    receiver = sftpPortClient.downloadFileBySftp("", receiveFile, Integer.parseInt(sftpType), sshKeyPassword);
                }
                    /*switch (Integer.parseInt(sftpType)){
                        //登录名和私钥
                        case 2:WriteBankLogLn("SFTP服务器连接中，请稍后...");receiver = sftpPortClient.downloadFile("",receiveFile);break;
                        //登录名和私钥和私钥密码
                        case 3:WriteBankLogLn("SFTP服务器连接中，请稍后...");receiver = sftpPortClient.downloadFilePrvkey("", receiveFile, sshKeyPassword);break;
                        //登录名和登录密码和私钥和私钥密码
                        case 4:WriteBankLogLn("SFTP服务器连接中，请稍后...");receiver = sftpPortClient.connectBySSHPrvkeyAndPsd("", receiveFile, sshKeyPassword);break;
                        default:WriteBankLogLn("配置暂不支持");
                    }*/
                sftpPortClient.disconnect();
                WriteBankLogLn("***********连接SFTP服务器结束***********");
                if (receiver.isCompleted) {
                    WriteBankLogLn("记录下载文件数量start");
                    if (StringHelper.isNullOrEmpty(receiver.connMsg)) {
                        WriteBankLogLn("从银行下载的文件数量：0");
                    } else {
                        fileList = Arrays.asList(receiver.connMsg.split("\\|"));
                        String fileStr = receiver.connMsg.replaceAll("\\|", "\r\n");
                        WriteBankLogLn("从银行下载的文件数量：" + fileList.size() + "下载的文件： \r\n" + fileStr);
                    }
                } else {
                    WriteBankLogLn("连接SFTP失败，请检查配置、通道是否正常。失败原因：\r\n" + receiver.connMsg);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            WriteBankLogLn("从sftp下载文件异常：" + e);
        }
    }

    /**
     * 获取待解析文件名称串
     *
     * @param decryptPath 待解析文件目录
     */
    public List<String> decryptFileName(String decryptPath) throws Exception {
        List<String> receiveFileList3 = new ArrayList<String>();
        //获取已解密未处理的文件
        String[] receiveFileList2 = new File(decryptPath).list();
        //处理已解密待解析的文件
        if (receiveFileList2 != null && receiveFileList2.length != 0) {
            //将MT940文件先解析
            String mt940Flag = bankConfig.getMapValueByKey("dealWithFileMapping", "MT940");
            if (StringHelper.hasAnyChar(mt940Flag)) {
                StringBuilder sb = new StringBuilder();
                for (String fileName : receiveFileList2) {
                    if (fileName.toUpperCase().contains(mt940Flag)) {
                        sb.insert(0, fileName + ",");
                    } else {
                        sb.append(fileName + ",");
                    }
                }
                receiveFileList3 = Arrays.asList(sb.toString().substring(0, sb.toString().length() - 1).split(","));
            }
        }
        return receiveFileList3;
    }

    /**
     * 解密文件
     *
     * @param receivePath 加密文件目录
     * @param decryptPath 解密后的文件目录
     * @param successPath 解密成功后的加密文件目录
     */
    public void decryptFile(String receivePath, String decryptPath, String successPath) {
        //开始解密sftp服务器下载的文件
        File file = new File(receivePath);
        if (file.listFiles().length > 0) {
            for (File file2 : file.listFiles()) {
                if (file2.isFile()) {
                    String fileContent = FileHelper.readFileText(file2.getPath(), charset);
                    if (file2.getName().contains(".pgp") || (!fileContent.contains(tag20) && !fileContent.contains("xml"))) {
                        //需要解密，进行解密
                        StringBuilder decryptFile = new StringBuilder(decryptPath);
                        if (file2.getName().contains(".pgp")) {
                            decryptFile.append(file2.getName().replace(".pgp", ".txt"));
                        } else if (!file2.getName().contains(".txt")) {
                            decryptFile.append(file2.getName()).append(".txt");
                        } else {
                            decryptFile.append(file2.getName());
                        }
                        String coPriKeyId = bankConfig.getValueAsString("coPriKeyId");
                        String coPriKeyPsword = bankConfig.getValueAsString("coPriKeyPsword");
                        //表示文件已经解析
                        GPGUtil.decryptCmdRun(file2.getPath(), decryptFile.toString(), coPriKeyId, coPriKeyPsword);
                        //GPGUtil.pgpDecryptAndVerify(file2.getPath(),decryptFile.toString(),charset);
                        //处理文件
                        if (FileHelper.existFile(decryptFile.toString())) {
                            WriteBankLogLn(file2.getName() + "解密报文成功");
                            String successFilePath = StringHelper.trimEndFileSp(successPath) + File.separator + Format.Date8Format.format(new Date()) + File.separator;
                            if (!FileHelper.existFile(successFilePath)) {
                                FileHelper.mkdir(successFilePath);
                            }
                            boolean flag = new File(file2.getPath()).renameTo(new File(successFilePath + file2.getName()));
                            if (flag) {
                                WriteBankLogLn("文件：" + file2.getPath() + " ---移动至---\r\n" + successFilePath + file2.getName() + "  成功");
                            } else {
                                WriteBankLogLn("文件：" + file2.getPath() + " ---移动至---\r\n" + successFilePath + file2.getName() + "  失败");
                            }
                        }
                    } else {
                        //不需要解密文件，直接将文件移动到解密后存放的文件夹里
                        renameTo(file2.getPath(), decryptPath + file2.getName());
                    }
                }
            }
        }
    }

    /**
     * 解析文件
     *
     * @param fileNameList 文件名称集合
     */
    public void analysisFile(List<String> fileNameList, String decryptPath, String successFilePath, String exceptionPath) {
        if (!fileNameList.isEmpty()) {
            String date = Format.Date8Format.format(new Date());
            //待解析文件
            if (!FileHelper.existFile(decryptPath)) {
                FileHelper.mkdir(decryptPath);
            }
            //解析成功的文件存放路径
            successFilePath = StringHelper.trimEndFileSp(successFilePath) + File.separator + date + File.separator;
            if (!FileHelper.existFile(successFilePath)) {
                FileHelper.mkdir(successFilePath);
            }
            //解析失败的文件存放路径
            exceptionPath = StringHelper.trimEndFileSp(exceptionPath) + File.separator + date + File.separator;
            if (!FileHelper.existFile(exceptionPath)) {
                FileHelper.mkdir(exceptionPath);
            }
            for (String fileName : fileNameList) {
                String fullName = decryptPath + fileName;
                if (FileHelper.existFile(fullName)) {
                    WriteBankLogLn("开始处理文件:" + fullName);
                    try {
                        //获取配置的要处理的文件。后续有其它需要处理的文件，请自行增加else if方法
                        String mt940Flag = bankConfig.getMapValueByKey("dealWithFileMapping", "MT940");
                        String mt942Flag = bankConfig.getMapValueByKey("dealWithFileMapping", "MT942");
                        String ackFlag = bankConfig.getMapValueByKey("dealWithFileMapping", "ACK");
                        if (StringHelper.hasAnyChar(mt942Flag) && fileTypeCheck(mt942Flag, fileName)) {//MT942
                            if ("HBC02".equals(bankFront.bankCode)) {
                                analysisMT942FileIsHBC(fullName, dealedPath);
                            } else {
                                analysisMT942File(fullName, dealedPath);
                            }
                            WriteBankLogLn(fullName + "解析完成，开始移除");
                            renameTo(fullName, successFilePath + fileName);
                            WriteBankLogLn(fullName + "移动到" + successFilePath + fileName);
                        } else if (StringHelper.hasAnyChar(mt940Flag) && fileTypeCheck(mt940Flag, fileName)) {//MT940
                            analysisMT940File(fullName, dealedPath);
                            WriteBankLogLn(fullName + "解析完成，开始移除");
                            renameTo(fullName, successFilePath + fileName);
                            WriteBankLogLn(fullName + "移动到" + successFilePath + fileName);
                        } else if (fileTypeCheck(ackFlag, fileName)) {//ACK
                            String className = "com.fingard.dsp.bank.directbank." + bankFront.bankCode.toLowerCase() + "." + bankFront.bankCode + "ForeignBank";
                            Class<?> bankClass = Class.forName(className);
                            DirectBase tmpDirectBase = (DirectBase) bankClass.newInstance();
                            tmpDirectBase.reqHeader = header;
                            tmpDirectBase.bankFront = bankFront;
                            tmpDirectBase.setSbLog(sblog);
                            IFileResolveDifference iBalance = (IFileResolveDifference) tmpDirectBase;
                            //解析ack文件
                            iBalance.analysisAckFile(fullName);
                            WriteBankLogLn(fullName + "解析完成，开始移除");
                            //analysisAckFile(fullName);
                            renameTo(fullName, successFilePath + fileName);
                            WriteBankLogLn(fullName + "移动到" + successFilePath + fileName);
                        }
                    } catch (Exception e) {
                        WriteBankLogLn("解析文件异常：" + e);
                        e.printStackTrace();
                        renameTo(fullName, exceptionPath + fileName);
                    }
                }
            }
        }
    }

    /**
     * 校验文件是否符合要求
     *
     * @param flag
     * @param fileName
     * @return
     */
    private boolean fileTypeCheck(String flag, String fileName) {
        if (StringHelper.hasAnyChar(flag)) {
            if (flag.contains(",")) {
                String[] ackAry = flag.split(",");
                for (String ack : ackAry) {
                    if (fileName.contains(ack)) {
                        return true;
                    }
                }
            } else {
                if (fileName.contains(flag)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 解析日终文件
     *
     * @param fullName
     * @throws Exception
     */
    public void analysisMT940File(String fullName, String dealedPath) throws Exception {
        //判断文件存不存在，不存在就不处理
        String context2 = FileHelper.readFileText(fullName, charset);
        if (StringHelper.isNullOrEmpty(context2)) {
            WriteBankLogLn("文件解析失败：-------" + fullName);
            throw new Exception("读取文件内容异常：" + fullName);
        }
        WriteBankLogLn("读取文件:" + fullName + "中的内容：\r\n" + context2);
        //截取要解析的数据内容
        if (StringHelper.hasAnyChar(startFlag)) {
            int start = 0;
            start = context2.indexOf(startFlag) + startFlag.length();
            String beginStr = context2.substring(0, start);
            do {
                context2 = context2.replace(beginStr, "");
            } while (context2.contains(beginStr));
        }
        if (StringHelper.hasAnyChar(endFlag) && context2.lastIndexOf(endFlag) != -1) {
            context2 = context2.substring(0, context2.lastIndexOf(endFlag));
        }
        //根据分隔符将明细数据分组
        String[] allContext = context2.split(splitFlag);
        //开始循环处理数据
        for (String context : allContext) {
            StringBuilder balanceContent = new StringBuilder();
            int tag61Start = context.indexOf(tag61);
            int tag62FStart = context.indexOf(presenceFlag(context, tag62F, tag62M));
            String allDetailContent = "";
            //如果有明细记录，就截取其中的明细长度，并去除原文中的明细长度
            if (tag61Start != -1) {
                tag61Start += tag61.length();
                allDetailContent = context.substring(tag61Start, tag62FStart);
                context = context.replace(allDetailContent, "").replace(tag61, "");
            }

            int offset, endset;
            //=====获取账号=====
            offset = context.indexOf(tag25) + tag25.length();
            endset = context.indexOf(tag28);
            String accountNum = context.substring(offset, endset).trim();
            //账号特殊格式
            String actType = bankConfig.getValueAsString("actType");
            if (StringHelper.hasAnyChar(actType) && actType.contains(accountNum.substring(0, 8))) {
                accountNum = accountNum.substring(8);
            }
            if ("HBC02".equals(bankFront.bankCode)) {
                accountNum = accountNum.substring(0, 14).replaceAll("-", "");
            }
            if ("SMBC01".equals(bankFront.bankCode)) {
                accountNum = accountNum.substring(accountNum.lastIndexOf("-") + "-".length());
            }
            //获取页码
            offset = context.indexOf(tag28) + tag28.length();
            endset = context.indexOf(presenceFlag(context, tag60F, tag60M));
            String page = context.substring(offset, endset);
            page = page.substring(page.indexOf("/") + 1).replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
            page = Integer.parseInt(page) + "";
            //获取序号
            String seqId = context.substring(offset, endset);
            seqId = seqId.substring(0, seqId.indexOf("/")).replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
            seqId = Integer.parseInt(seqId) + "";
            //=====获取日初余额=====
            offset = context.indexOf(presenceFlag(context, tag60F, tag60M)) + presenceFlag(context, tag60F, tag60M).length();
            endset = context.indexOf(presenceFlag(context, tag62F, tag62M));
            String openBalEnd = context.substring(offset, endset).replaceAll(",", ".").trim();
            String openBal = openBalEnd.substring(10);
            openBal = amtCheck(openBal);
            openBal = getAmount(openBalEnd.substring(0, 1), openBal);
            //=====获取日终余额、日期、币种=====
            String banlanceEnd = "";
            offset = context.indexOf(presenceFlag(context, tag62F, tag62M)) + presenceFlag(context, tag62F, tag62M).length();
            if (StringHelper.isNullOrEmpty(presenceFlag(context, tag64, tag65))) {
                if (context.substring(offset).contains(tag86)) {
                    endset = context.substring(offset).indexOf(tag86);
                    banlanceEnd = context.substring(offset, endset).trim();
                } else {
                    banlanceEnd = context.substring(offset).trim();
                }
            } else {
                endset = context.indexOf(presenceFlag(context, tag64, tag65));
                banlanceEnd = context.substring(offset, endset).trim();
            }
            //获取日期
            String date1 = "20" + banlanceEnd.substring(1, 7);
            //获取币种
            String cur = banlanceEnd.substring(7, 10);
            //有的账号中会有币种信息,导致解析失败
//            if ("BNPP02".equals(bankFront.bankCode)) {
//                if (accountNum.endsWith(cur)) {
//                    accountNum = accountNum.substring(0, accountNum.length() - 3);
//                } else if (accountNum.startsWith(cur)) {
//                    accountNum = accountNum.substring(4);
//                }
//            }
            //获取日终余额
            String banlance = banlanceEnd.substring(10).replace(",", ".").trim();
            banlance = amtCheck(banlance);
            banlance = getAmount(banlanceEnd.substring(0, 1), banlance);
            //=====获取日终可用余额=====
            String availBal = "";
            String cdFlag = "";
            if (!context.contains(tag64)) {//如果未返回64节点，则 当前可用=当前
                WriteBankLogLn("64节点不存在");
                availBal = banlance;
            } else {
                WriteBankLogLn("64节点存在");
                offset = context.indexOf(tag64) + tag64.length();
                if (!context.contains(tag65)) {
                    if (context.substring(offset).contains(tag86)) {
                        availBal = context.substring(offset, context.indexOf(tag86)).substring(10).replace(",", ".").trim();
                        cdFlag = context.substring(offset, context.indexOf(tag86)).substring(0, 1);
                    } else {
                        availBal = context.substring(offset).substring(10).replace(",", ".").trim();
                        cdFlag = context.substring(offset).substring(0, 1);
                    }
                } else {
                    availBal = context.substring(offset, context.indexOf(tag65)).substring(10).replace(",", ".").trim();
                    cdFlag = context.substring(offset, context.indexOf(tag65)).substring(0, 1);
                }
            }
            availBal = amtCheck(availBal);
            availBal = getAmount(cdFlag, availBal);

            //已解析文件数据
            StringBuilder fileContent = new StringBuilder();
            fileContent.append(accountNum).append(date1).append(seqId).append(page);//账号日期序号页码币种
            if("true".equals(bankConfig.getValueAsString("IsPlayCurGroup"))){
                fileContent.append(cur);
            }
            if ("HBC02".equals(bankFront.bankCode)) {
                fileContent.append("940");
            }
            //已解析数据存放位置
            String endFile = StringHelper.trimEndFileSp(dealedPath) + File.separator + date1 + File.separator + "MTEndDetailContent.txt";
            //判断条件'账号序号页码日期'是否存在已解析记录
            if (!isExist(fileContent.toString(), endFile)) {
                //账号|币种|期终余额|可用余额|期初余额|页码|
                String dealedFile = StringHelper.trimEndFileSp(dealedPath) + File.separator + date1 + File.separator
                        + "MT940" + File.separator + accountNum;
                if("true".equals(bankConfig.getValueAsString("IsPlayCurGroup"))){
                    dealedFile+=cur;
                }
                dealedFile+="_7505.txt";
                if (FileHelper.existFile(dealedFile)) {
                    String hisContent = FileHelper.readFileText(dealedFile, charset);
                    String[] hisBal = hisContent.split("\\|");
                    if (hisBal.length > 5) {
                        //收到后一页的数据，除了期初余额不更新，其它全部更新
                        if (Integer.parseInt(page) > Integer.parseInt(hisBal[5])) {
                            balanceContent.append(accountNum + "|").append(cur + "|").append(banlance + "|").append(availBal + "|")
                                    .append(hisBal[4] + "|").append(page + "|");
                            FileHelper.writeFile(dealedFile, balanceContent.toString(), charset);
                            WriteBankLogLn("更新文件：" + dealedFile + ",文件内容 \r\n" + balanceContent.toString());
                            //收到前一页的数据，只更新期初余额
                        } else if (Integer.parseInt(page) < Integer.parseInt(hisBal[5])) {
                            balanceContent.append(hisBal[0] + "|").append(hisBal[1] + "|").append(hisBal[2] + "|").append(hisBal[3] + "|")
                                    .append(openBal + "|").append(hisBal[5] + "|");
                            FileHelper.writeFile(dealedFile, balanceContent.toString(), charset);
                            WriteBankLogLn("更新文件：" + dealedFile + ",文件内容 \r\n" + balanceContent.toString());
                        } else {
                            WriteBankLogLn("中间数据，无需更新余额");
                        }
                    } else {
                        WriteBankLogLn("文件" + dealedFile + "数据异常：" + hisContent);
                    }
                } else {
                    balanceContent.append(accountNum + "|").append(cur + "|").append(banlance + "|").append(availBal + "|").append(openBal + "|").append(page + "|");
                    FileHelper.writeFile(dealedFile, balanceContent.toString(), charset);
                    WriteBankLogLn("写入文件：" + dealedFile + ",文件内容 \r\n" + balanceContent.toString());
                }

                //记录已解析过的数据
                FileHelper.appendFile(endFile, fileContent.append("\r\n").toString(), charset);
                WriteBankLogLn("备注：写入文件：" + endFile + ",文件内容 \r\n" + fileContent.toString());

                //解析历史明细
                if (!StringHelper.isNullOrEmpty(allDetailContent)) {
                    WriteBankLogLn("余额计算完成，开始解析明细");
                    if ("HBC02".equals(bankFront.bankCode)) {
                        dealTransDetailIsHBC(allDetailContent.split(tag61), accountNum, date1, cur, "MT940", "");
                    } else {
                        dealTransDetail(allDetailContent.split(tag61), accountNum, openBal, date1, cur, "MT940", "0", "");
                    }
                    WriteBankLogLn("明细解析完成");
                }
            } else {
                WriteBankLogLn("文件" + fullName + "数据已被解析过");
            }
        }
    }

    /**
     * 根据借贷标识改变金额的正负值
     *
     * @param cdFlag
     * @param Amount
     * @return
     */
    private String getAmount(String cdFlag, String Amount) {
        if ("D".equals(cdFlag)) {
            Amount = "-" + Amount;
        }
        return Amount;
    }

    /**
     * 解析61和86数据
     *
     * @param allDetailContent 明细记录
     * @param accountNum       账号
     * @param balance          上一次交易的当前余额
     * @param date             支付当天 yyyyMMdd
     * @param cur              币种
     * @param fileType         文件类型('MT940','MT942')
     * @param actType          账户类型 1新账户 0非新账户
     * @param transTime        交易时间
     * @throws Exception
     */
    public void dealTransDetail(String[] allDetailContent, String accountNum, String balance, String date, String cur, String fileType, String actType, String transTime) throws Exception {
        //账户余额
        BigDecimal decimal = new BigDecimal(balance);
        String file = "";
        if ("MT942".equals(fileType)) {
            file = dealedPath + date + File.separator + fileType + File.separator + accountNum;
            if("true".equals(bankConfig.getValueAsString("IsPlayCurGroup"))){
                file+=cur;
            }
            file+="_7515.txt";
            WriteBankLogLn("文件类型：" + fileType + ",创建明细文件:" + file);
        } else if ("MT940".equals(fileType)) {
            file = dealedPath + date + File.separator + fileType + File.separator + accountNum;
            if("true".equals(bankConfig.getValueAsString("IsPlayCurGroup"))){
                file+=cur;
            }
            file+="_7516.txt";
            WriteBankLogLn("文件类型：" + fileType + ",创建明细文件:" + file);
        } else {
            throw new Exception("fileType参数不规范：" + fileType);
        }
        StringBuilder transDetail = new StringBuilder();
        for (String detailUnit : allDetailContent) {
            String valueDate = "";//起息日期
            String tranDate = "";//交易日期
            String transAmt = "";//交易金额
            String cdFlag = "";//借贷标识
            String reqId = "";//付款请求流水号
            String[] detailsplit = detailUnit.split(tag86);//[0] tag61   [1] tag86
            if (StringHelper.isNullOrEmpty(detailsplit[0])) {
                throw new Exception("61字段缺失，数据异常请检查：" + detailsplit);
            }
            if (detailsplit.length == 1) {//不存在86节点
                detailsplit = new String[]{detailsplit[0], " "};
            }
            //=====tag61=====
            //起息日期
            int index2 = 0;
            String tranTime = "";
            valueDate = "20" + detailsplit[0].substring(0, 6);
            valueDate = Format.Date10Format.format(Format.Date8Format.parse(valueDate));
            if (isLetter(detailsplit[0].substring(6, 7).charAt(0))) {
                //交易日期
                tranDate = valueDate;
                if (StringHelper.hasAnyChar(transTime) && transTime.length() == 8) {
                    tranTime = tranDate + " " + transTime;
                } else {
                    tranTime = tranDate + " 00:00:00";
                }
                //借贷标识 D C RC RD EC ED
                cdFlag = detailsplit[0].charAt(6) + "";
                index2 = 6;
                if ("R".equals(cdFlag) || "E".equals(cdFlag)) {
                    cdFlag = detailsplit[0].substring(6, 8);
                    index2 = 7;
                }
            } else {
                //交易日期
                tranDate = "20" + detailsplit[0].substring(0, 2) + detailsplit[0].substring(6, 10);
                tranDate = Format.Date10Format.format(Format.Date8Format.parse(tranDate));
                if (StringHelper.hasAnyChar(transTime) && transTime.length() == 8) {
                    tranTime = tranDate + " " + transTime;
                } else {
                    tranTime = tranDate + " 00:00:00";
                }
                //借贷标识 D C RC RD
                cdFlag = detailsplit[0].charAt(10) + "";
                index2 = 10;
                if ("R".equals(cdFlag) || "E".equals(cdFlag)) {
                    cdFlag = detailsplit[0].substring(10, 12);
                    index2 = 11;
                }
            }
            //判断借贷表示
            if ("RD".equals(cdFlag)) {
                //cdFlag=cdFlag.substring(1);
                //transAmt="-"+transAmt;
                cdFlag = "C";
            } else if ("RC".equals(cdFlag)) {
                cdFlag = "D";
            }
            if (cdFlag.contains("E")) {
                cdFlag = cdFlag.substring(1);
            }
            if (isLetter(detailsplit[0].substring(index2 + 1).charAt(0))) {
                index2 = index2 + 1;
            }
            //交易金额
            //校验61节点金额是否返回小数点
            int num1 = 0;//获取交易流水号的起始位置
            int index = detailsplit[0].indexOf(",", index2) + 1;
            if (isLetter(detailsplit[0].substring(index, index + 1).charAt(0))) {
                //说明没有返回小数点
                index = detailsplit[0].indexOf(",", index2) + 1;
                num1 = detailsplit[0].indexOf(",", index2) + 5;
            } else {
                //说明返回小数点
                index = detailsplit[0].indexOf(",", index2) + 3;
                num1 = detailsplit[0].indexOf(",", index2) + 7;
            }
            transAmt = detailsplit[0].substring(index2 + 1, index).replace(",", ".");
            transAmt = amtCheck(transAmt);
            //截取61金额后面的字符串
            String flag = detailsplit[0].substring(index2 + 1, index);
            String tag61String = detailsplit[0].substring(detailsplit[0].indexOf(flag) + flag.length());
            tag61String = tag61String.replace("\r", "").replace("\n", "");
            if (tag61String.length() > 4) {
                //付款请求流水号
                int num2 = 0;
                //
                if (detailsplit[0].substring(num1).contains("//")) {
                    num2 = detailsplit[0].indexOf("//", num1);
                } else {
                    num2 = detailsplit[0].indexOf("\r\n", num1);
                }
                reqId = detailsplit[0].substring(num1, num2);
            } else {
                reqId = " ";
            }
            //=====tag86=====
            Map<String, String> map = new HashMap<String, String>();
            map.put("recAct", "");
            map.put("recName", "");
            map.put("recBankName", "");
            map.put("recDetail", "");
            if ("2".equals(bankConfig.getValueAsString("mtAnalysisType"))) {
                //Map<String,String> map=new HashMap<String, String>();
                if (detailsplit.length == 2 && StringHelper.hasAnyChar(detailsplit[1])) {
                    String className = "com.fingard.dsp.bank.directbank." + bankFront.bankCode.toLowerCase() + "." + bankFront.bankCode + "ForeignBank";
                    Class<?> bankClass = Class.forName(className);
                    DirectBase tmpDirectBase = (DirectBase) bankClass.newInstance();
                    tmpDirectBase.reqHeader = header;
                    tmpDirectBase.bankFront = bankFront;
                    tmpDirectBase.setSbLog(sblog);
                    IFileResolveDifference iBalance = (IFileResolveDifference) tmpDirectBase;
                    //获取交易对手信息和附言
                    map = iBalance.getRecInformationMap(detailsplit[1]);
                }
            } else {
                if (StringHelper.hasAnyChar(tag61String)) {
                    map.put("recDetail", detailsplit[1] + "##" + tag61String);
                } else {
                    map.put("recDetail", detailsplit[1]);
                }
            }

            if ("C".equals(cdFlag)) {
                decimal = decimal.add(new BigDecimal(transAmt));
            } else if ("D".equals(cdFlag)) {
                decimal = decimal.subtract(new BigDecimal(transAmt));
            }
            if ("1".equals(actType)) {
                decimal = new BigDecimal("0.00");
            }
            //账号 | 币种 | 交易日期| 交易时间| 计息日期 | 交易金额 |借贷标识| 账户余额 |对方账号|
            //                    对方户名 | 对方银行 |用途| 付款请求流水号 |
            DecimalFormat format = new DecimalFormat("0.00");
            //交易当天的明细统一把交易日期设为当天
            if (!tranDate.equals(DateHelper.convertD8toD10(date))) {
                tranTime = tranTime.replaceAll(tranDate, DateHelper.convertD8toD10(date));
                tranDate = DateHelper.convertD8toD10(date);
            }
            String[] detail = new String[]{accountNum, cur, tranDate, tranTime, valueDate, transAmt, cdFlag, format.format(decimal),
                    StringHelper.isNullOrEmpty(map.get("recAct")) ? " " : map.get("recAct"), StringHelper.isNullOrEmpty(map.get("recName")) ? " " : map.get("recName"),
                    StringHelper.isNullOrEmpty(map.get("recBankName")) ? " " : map.get("recBankName"), StringHelper.isNullOrEmpty(map.get("recDetail")) ? " " : map.get("recDetail"),
                    StringHelper.isNullOrEmpty(map.get("reqId")) ? reqId : map.get("reqId")};
            for (int i = 0; i < detail.length; i++) {
                if (i < detail.length - 1) {
                    transDetail.append(detail[i].replaceAll("[\\r\\n]", "") + "|");
                } else {
                    transDetail.append(detail[i].replaceAll("[\\r\\n]", "") + "\r\n");
                }
            }
        }
        FileHelper.appendFile(file, transDetail.toString(), charset);
        WriteBankLogLn("追加文件：" + file + ",追加明细内容 \r\n" + transDetail.toString());
    }

    /**
     * 解析MT942文件
     *
     * @param fullName
     * @param dealedPath 解析后存放的位置
     * @throws Exception
     */
    public void analysisMT942File(String fullName, String dealedPath) throws Exception {
        //判断文件存不存在，不存在就不处理
        String context2 = FileHelper.readFileText(fullName, charset);
        if (StringHelper.isNullOrEmpty(context2)) {
            WriteBankLogLn("文件解析失败：-------" + fullName);
            return;
        }
        WriteBankLogLn("读取文件:" + fullName + "中的内容：\r\n" + context2);
        //截取要解析的数据内容
        if (StringHelper.hasAnyChar(startFlag)) {
            int start = 0;
            start = context2.indexOf(startFlag) + startFlag.length();
            String beginStr = context2.substring(0, start);
            do {
                context2 = context2.replace(beginStr, "");
            } while (context2.contains(beginStr));
        }
        if (StringHelper.hasAnyChar(endFlag) && context2.lastIndexOf(endFlag) != -1) {
            context2 = context2.substring(0, context2.lastIndexOf(endFlag));
        }
        //根据分隔符将明细数据分组
        String[] allContext = context2.split(splitFlag);
        //开始循环处理数据
        for (String context : allContext) {
            StringBuilder balanceContent = new StringBuilder();
            int tag61Start = context.indexOf(tag61);
            int tag90DStart = 0;
            if (context.contains(tag90D)) {
                tag90DStart = context.indexOf(tag90D);
            } else {
                tag90DStart = context.indexOf(tag90C);
            }
            String allDetailContent = "";
            //拆分出61和86
            if (tag61Start != -1) {
                tag61Start += tag61.length();
                allDetailContent = context.substring(tag61Start, tag90DStart);
                context = context.replace(allDetailContent, "").replace(tag61, "");
            }
            int offset, endset;
            //获取账号
            offset = context.indexOf(tag25) + tag25.length();
            endset = context.indexOf(tag28);
            String accountNum = context.substring(offset, endset).trim();
            //三菱账号特殊格式
            String actType = bankConfig.getValueAsString("actType");
            if (StringHelper.hasAnyChar(actType) && actType.contains(accountNum.substring(0, 8))) {
                accountNum = accountNum.substring(8);
            }
            //获取页码
            offset = context.indexOf(tag28) + tag28.length();
            endset = context.indexOf(tag34F);
            String page = context.substring(offset, endset);
            page = page.substring(page.indexOf("/") + 1).replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
            page = Integer.parseInt(page) + "";
            //获取序号
            String seqId = context.substring(offset, endset);
            seqId = seqId.substring(0, seqId.indexOf("/")).replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
            seqId = Integer.parseInt(seqId) + "";
            //账户当天的时间
            offset = context.indexOf(tag13D) + tag13D.length();
            if (context.contains(tag90D)) {
                endset = context.indexOf(tag90D);
            } else {
                endset = context.indexOf(tag90C);
            }
            String date = "20" + context.substring(offset, endset).substring(0, 6);//文件生成日期
            String date2 = context.substring(offset, endset).substring(0, 10);
            String time = date2.substring(6);//文件生成时间
            time = time.substring(0, 2) + ":" + time.substring(2, 4) + ":" + "00";
            String tranDate = Format.Date10Format.format(Format.Date8Format.parse(date));
            //获取账户币种
            offset = context.indexOf(tag34F) + tag34F.length();
            String cur = context.substring(offset, offset + 3);
//            if ("BNPP02".equals(bankFront.bankCode)) {
//                if (accountNum.endsWith(cur)) {
//                    accountNum = accountNum.substring(0, accountNum.length() - 3);
//                } else if (accountNum.startsWith(cur)) {
//                    accountNum = accountNum.substring(4);
//                }
//            }
            //获取期初余额，当前余额，当前可用余额，上次交易后的余额
            WriteBankLogLn("开始计算余额");
            Map<String, String> map = null;
            if ("2".equals(bankConfig.getValueAsString("mtAnalysisType"))) {
                String className = "com.fingard.dsp.bank.directbank." + bankFront.bankCode.toLowerCase() + "." + bankFront.bankCode + "ForeignBank";
                Class<?> bankClass = Class.forName(className);
                DirectBase tmpDirectBase = (DirectBase) bankClass.newInstance();
                tmpDirectBase.reqHeader = header;
                tmpDirectBase.bankFront = bankFront;
                tmpDirectBase.setSbLog(sblog);
                IFileResolveDifference iBalance = (IFileResolveDifference) tmpDirectBase;
                //获取期初余额，当前余额，可用余额，上一次交易余额
                map = iBalance.getBalanceMap(context, accountNum, date);
            } else {
                map = getBalanceMap(context, accountNum, date);
            }
            //已解析文件数据
            StringBuilder fileContent = new StringBuilder();
            fileContent.append(accountNum).append(date).append(seqId).append(page);//账号日期序号页码币种
            if("true".equals(bankConfig.getValueAsString("IsPlayCurGroup"))){
                fileContent.append(cur);
            }
            //已解析数据存放位置
            String endFile = StringHelper.trimEndFileSp(dealedPath) + File.separator + date + File.separator + "MTEndDetailContent.txt";
            //判断条件'账号序号页码日期'是否存在已解析记录
            if (!isExist(fileContent.toString(), endFile) && map.size() > 0) {
                // 余额结果：账号|币种|当前余额|可用余额|期初余额|
                String dealedFile = StringHelper.trimEndFileSp(dealedPath) + File.separator + date + File.separator
                        + "MT942" + File.separator + accountNum;
                if("true".equals(bankConfig.getValueAsString("IsPlayCurGroup"))){
                    dealedFile+=cur;
                }
                dealedFile+="_7506.txt";
                //生成余额文件7506
                balanceContent.append(accountNum + "|").append(cur + "|").append(map.get("closeBal") + "|").append(map.get("availBal") + "|")
                        .append(map.get("openBal") + "|");
                FileHelper.writeFile(dealedFile, balanceContent.toString(), charset);
                WriteBankLogLn("余额：写入文件：" + dealedFile + ",文件内容 \r\n" + balanceContent.toString());
                //记录已解析过的数据
                FileHelper.appendFile(endFile, fileContent.append("\r\n").toString(), charset);
                WriteBankLogLn("备注：写入文件：" + endFile + ",文件内容 \r\n" + fileContent.toString());
                //解析明细，生成明细文件7515
                if (!StringHelper.isNullOrEmpty(allDetailContent)) {
                    WriteBankLogLn("余额计算完成，开始解析明细数据");
                    dealTransDetail(allDetailContent.split(tag61), accountNum, map.get("lastBal"), date, cur, "MT942", map.get("new"), time);
                    WriteBankLogLn("明细数据解析完成");
                }
            } else {
                WriteBankLogLn("文件" + fullName + "数据已被解析过");
            }
        }
    }

    /**
     * 判断字符串是否存在文件中
     *
     * @param detail
     * @param filePath
     * @return
     */
    private boolean isExist(String detail, String filePath) {
        boolean flag = false;
        BufferedReader reader = null;
        try {
            File file = new File(filePath);
            if (file.exists() && file.isFile()) {
                InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), charset);
                reader = new BufferedReader(isr);
                String readLine = "";
                while ((readLine = reader.readLine()) != null) {
                    if (detail.equals(readLine)) {
                        flag = true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }

    /**
     * 解析MT942文件：恒生银行特殊处理方式
     *
     * @param fullName
     * @param dealedPath 解析后存放的位置
     * @throws Exception
     */
    public void analysisMT942FileIsHBC(String fullName, String dealedPath) throws Exception {
        //判断文件存不存在，不存在就不处理
        String context2 = FileHelper.readFileText(fullName, charset);
        if (StringHelper.isNullOrEmpty(context2)) {
            WriteBankLogLn("文件解析失败：-------" + fullName);
            return;
        }
        WriteBankLogLn("读取文件:" + fullName + "中的内容：\r\n" + context2);
        //截取要解析的数据内容
        int start = 0;
        if (StringHelper.hasAnyChar(startFlag)) {
            start = context2.indexOf(startFlag) + startFlag.length();
        }
        if (StringHelper.hasAnyChar(endFlag) && context2.lastIndexOf(endFlag) != -1) {
            context2 = context2.substring(start, context2.lastIndexOf(endFlag));
        } else {
            context2 = context2.substring(start);
        }
        //根据分隔符将明细数据分组
        String[] allContext = context2.split(splitFlag);
        //开始循环处理数据
        for (String context : allContext) {
            StringBuilder balanceContent = new StringBuilder();
            int tag61Start = context.indexOf(tag61);
            String allDetailContent = "";
            //拆分出61和86
            if (tag61Start != -1) {
                tag61Start += tag61.length();
                allDetailContent = context.substring(tag61Start);
                context = context.replace(allDetailContent, "").replace(tag61, "");
            }
            int offset, endset;
            //获取账号
            offset = context.indexOf(tag25) + tag25.length();
            endset = context.indexOf(tag28);
            String accountNum = context.substring(offset, endset).trim();
            //账号特殊格式
            String actType = bankConfig.getValueAsString("actType");
            if (StringHelper.hasAnyChar(actType) && actType.contains(accountNum.substring(0, 8))) {
                accountNum = accountNum.substring(8);
            }
            if ("HBC02".equals(bankFront.bankCode)) {
                accountNum = accountNum.substring(0, 14).replaceAll("-", "");
            }
            //获取页码
            offset = context.indexOf(tag28) + tag28.length();
            endset = context.indexOf(tag34F);
            String page = context.substring(offset, endset);
            page = page.substring(page.indexOf("/") + 1).replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
            page = Integer.parseInt(page) + "";
            //获取序号
            String seqId = context.substring(offset, endset);
            seqId = seqId.substring(0, seqId.indexOf("/")).replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
            seqId = Integer.parseInt(seqId) + "";
            //账户当天的时间
            offset = context.indexOf(tag13D) + tag13D.length();
            String date = "20" + context.substring(offset).substring(0, 6);//文件生成日期
            //获取账户币种
            offset = context.indexOf(tag34F) + tag34F.length();
            String cur = context.substring(offset, offset + 3);
            //获取期初余额，当前余额，当前可用余额，上次交易后的余额
            WriteBankLogLn("开始计算余额");
            Map<String, String> map = null;
            String className = "com.fingard.dsp.bank.directbank." + bankFront.bankCode.toLowerCase() + "." + bankFront.bankCode + "ForeignBank";
            Class<?> bankClass = Class.forName(className);
            DirectBase tmpDirectBase = (DirectBase) bankClass.newInstance();
            tmpDirectBase.reqHeader = header;
            tmpDirectBase.bankFront = bankFront;
            tmpDirectBase.setSbLog(sblog);
            IFileResolveDifference iBalance = (IFileResolveDifference) tmpDirectBase;
            //获取期初余额，当前余额，可用余额，上一次交易余额
            map = iBalance.getBalanceMap(allDetailContent, accountNum, date);
            //已解析文件数据
            StringBuilder fileContent = new StringBuilder();
            fileContent.append(accountNum).append(date).append(seqId).append(page);//账号日期序号页码
            //已解析数据存放位置
            String endFile = StringHelper.trimEndFileSp(dealedPath) + File.separator + date + File.separator + "MTEndDetailContent.txt";
            //判断条件'账号序号页码日期'是否存在已解析记录
            if (!isExist(fileContent.toString(), endFile) && map.size() > 0) {
                // 余额结果：账号|币种|当前余额|可用余额|期初余额|
                String dealedFile = StringHelper.trimEndFileSp(dealedPath) + File.separator + date + File.separator
                        + "MT942" + File.separator + accountNum + "_7506.txt";
                //生成余额文件7506
                balanceContent.append(accountNum + "|").append(cur + "|").append(map.get("closeBal") + "|").append(map.get("availBal") + "|")
                        .append(map.get("openBal") + "|");
                FileHelper.writeFile(dealedFile, balanceContent.toString(), charset);
                WriteBankLogLn("余额：写入文件：" + dealedFile + ",文件内容 \r\n" + balanceContent.toString());
                //记录已解析过的数据
                FileHelper.appendFile(endFile, fileContent.append("\r\n").toString(), charset);
                WriteBankLogLn("备注：写入文件：" + endFile + ",文件内容 \r\n" + fileContent.toString());
                //解析明细，生成明细文件7515
                if (!StringHelper.isNullOrEmpty(allDetailContent)) {
                    WriteBankLogLn("余额计算完成，开始解析明细数据");
                    dealTransDetailIsHBC(allDetailContent.split(tag61), accountNum, date, cur, "MT942", "");
                    WriteBankLogLn("明细数据解析完成");
                }
            } else {
                WriteBankLogLn("文件" + fullName + "数据已被解析过");
            }
        }
    }

    /**
     * 解析61和86数据
     *
     * @param allDetailContent 明细记录
     * @param accountNum       账号
     * @param date             支付当天 yyyyMMdd
     * @param cur              币种
     * @param fileType         文件类型('MT940','MT942')
     * @param transTime        交易时间
     * @throws Exception
     */
    public void dealTransDetailIsHBC(String[] allDetailContent, String accountNum, String date, String cur, String fileType, String transTime) throws Exception {
        String file = "";
        if ("MT942".equals(fileType)) {
            file = dealedPath + date + File.separator + fileType + File.separator + accountNum + "_7515.txt";
            WriteBankLogLn("文件类型：" + fileType + ",创建明细文件:" + file);
        } else if ("MT940".equals(fileType)) {
            file = dealedPath + date + File.separator + fileType + File.separator + accountNum + "_7516.txt";
            WriteBankLogLn("文件类型：" + fileType + ",创建明细文件:" + file);
        } else {
            throw new Exception("fileType参数不规范：" + fileType);
        }
        StringBuilder transDetail = new StringBuilder();
        for (String detailUnit : allDetailContent) {
            String valueDate = "";//起息日期
            String tranDate = "";//交易日期
            String transAmt = "";//交易金额
            String cdFlag = "";//借贷标识
            //String reqId = "";//付款请求流水号
            String[] detailsplit = detailUnit.split(tag86);//[0] tag61   [1] tag86
            if (StringHelper.isNullOrEmpty(detailsplit[0])) {
                throw new Exception("61字段缺失，数据异常请检查：" + detailsplit);
            }
            if (detailsplit.length == 1) {//不存在86节点
                detailsplit = new String[]{detailsplit[0], " "};
            }
            //=====tag61=====
            //起息日期
            int index2 = 0;
            String tranTime = "";
            valueDate = "20" + detailsplit[0].substring(0, 6);
            valueDate = Format.Date10Format.format(Format.Date8Format.parse(valueDate));
            if (isLetter(detailsplit[0].substring(6, 7).charAt(0))) {
                //交易日期
                tranDate = valueDate;
                if (StringHelper.hasAnyChar(transTime) && transTime.length() == 8) {
                    tranTime = tranDate + " " + transTime;
                } else {
                    tranTime = tranDate + " 00:00:00";
                }
                //借贷标识 D C RC RD EC ED
                cdFlag = detailsplit[0].charAt(6) + "";
                index2 = 6;
                if ("R".equals(cdFlag) || "E".equals(cdFlag)) {
                    cdFlag = detailsplit[0].substring(6, 8);
                    index2 = 7;
                }
            } else {
                //交易日期
                tranDate = "20" + detailsplit[0].substring(0, 2) + detailsplit[0].substring(6, 10);
                tranDate = Format.Date10Format.format(Format.Date8Format.parse(tranDate));
                if (StringHelper.hasAnyChar(transTime) && transTime.length() == 8) {
                    tranTime = tranDate + " " + transTime;
                } else {
                    tranTime = tranDate + " 00:00:00";
                }
                //借贷标识 D C RC RD
                cdFlag = detailsplit[0].charAt(10) + "";
                index2 = 10;
                if ("R".equals(cdFlag) || "E".equals(cdFlag)) {
                    cdFlag = detailsplit[0].substring(10, 12);
                    index2 = 11;
                }
            }
            //判断借贷表示
            if ("RD".equals(cdFlag)) {
                cdFlag = "C";
            } else if ("RC".equals(cdFlag)) {
                cdFlag = "D";
            }
            if (cdFlag.contains("E")) {
                cdFlag = cdFlag.substring(1);
            }
            if (isLetter(detailsplit[0].substring(index2 + 1).charAt(0))) {
                index2 = index2 + 1;
            }
            //交易金额
            //校验61节点金额是否返回小数点
            int index = detailsplit[0].indexOf(",", index2) + 1;
            int count=1;//记录返回几位小数,最多判断三位
            for(int i=0;i<3;i++){
                if(!isLetter(detailsplit[0].substring(index+i, index + 1 + i).charAt(0))){
                    count++;
                }else {
                    break;
                }
            }
            //说明没有返回小数点
            index=detailsplit[0].indexOf(",", index2) + count;
            /*if (isLetter(detailsplit[0].substring(index, index + 1).charAt(0))) {
                //说明没有返回小数点
                index = detailsplit[0].indexOf(",", index2) + 1;
            } else {
                //说明返回小数点
                index = detailsplit[0].indexOf(",", index2) + 3;
            }*/
            transAmt = detailsplit[0].substring(index2 + 1, index).replace(",", ".");
            transAmt = amtCheck(transAmt);
            //=====tag86=====
            Map<String, String> map = new HashMap<String, String>();
            map.put("recAct", "");
            map.put("recName", "");
            map.put("recBankName", "");
            map.put("recDetail", "");
            map.put("reqId", "");
            if (detailsplit.length == 2 && StringHelper.hasAnyChar(detailsplit[1])) {
                String className = "com.fingard.dsp.bank.directbank." + bankFront.bankCode.toLowerCase() + "." + bankFront.bankCode + "ForeignBank";
                Class<?> bankClass = Class.forName(className);
                DirectBase tmpDirectBase = (DirectBase) bankClass.newInstance();
                tmpDirectBase.reqHeader = header;
                tmpDirectBase.bankFront = bankFront;
                tmpDirectBase.setSbLog(sblog);
                IFileResolveDifference iBalance = (IFileResolveDifference) tmpDirectBase;
                //获取交易对手信息和附言
                map = iBalance.getRecInformationMap(cdFlag + "#@#" + detailsplit[1]);
            }
            //账户余额
            //解析86
            String[] contentOne86 = detailsplit[1].split("\r\n");
            //提取余额：干掉,号，转成double不报错则为余额
            String balance = "";
            for (String content : contentOne86) {
                try {
                    balance = Double.parseDouble(content.replaceAll(",", "")) + "";
                } catch (Exception e) {
                    continue;
                }
                if (StringHelper.hasAnyChar(balance)) {
                    continue;
                }
            }
            if(StringHelper.hasAnyChar(balance)){
                balance = new BigDecimal(balance) + "";
            }else {
                balance = "0.00";
            }
            //账号 | 币种 | 交易日期| 交易时间| 计息日期 | 交易金额 |借贷标识| 账户余额 |对方账号|
            //                    对方户名 | 对方银行 |用途| 付款请求流水号 |
            //交易当天的明细统一把交易日期设为当天
            if (!tranDate.equals(DateHelper.convertD8toD10(date))) {
                tranTime = tranTime.replaceAll(tranDate, DateHelper.convertD8toD10(date));
                tranDate = DateHelper.convertD8toD10(date);
            }
            String[] detail = new String[]{accountNum, cur, tranDate, tranTime, valueDate, transAmt, cdFlag, balance,
                    StringHelper.isNullOrEmpty(map.get("recAct")) ? " " : map.get("recAct"), StringHelper.isNullOrEmpty(map.get("recName")) ? " " : map.get("recName"),
                    StringHelper.isNullOrEmpty(map.get("recBankName")) ? " " : map.get("recBankName"), StringHelper.isNullOrEmpty(map.get("recDetail")) ? " " : map.get("recDetail"),
                    StringHelper.isNullOrEmpty(map.get("reqId")) ? " " : map.get("reqId")};
            for (int i = 0; i < detail.length; i++) {
                if (i < detail.length - 1) {
                    transDetail.append(detail[i].replaceAll("[\\r\\n]", "") + "|");
                } else {
                    transDetail.append(detail[i].replaceAll("[\\r\\n]", "") + "\r\n");
                }
            }
        }
        FileHelper.appendFile(file, transDetail.toString(), charset);
        WriteBankLogLn("追加文件：" + file + ",追加明细内容 \r\n" + transDetail.toString());
    }

    /**
     * MT942中获取期初余额，当前余额，当前可用余额，上次交易后的余额
     *
     * @param context
     * @param accountNum
     * @param date
     * @return
     * @throws Exception
     */
    private Map<String, String> getBalanceMap(String context, String accountNum, String date) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        //获取出账总金额
        int offset = 0;
        int endset = 0;
        int startIndex = 0;
        String outBal = "0";
        if (context.contains(tag90D)) {
            offset = context.indexOf(tag90D) + tag90D.length();
            if (context.contains(tag90C)) {
                endset = context.indexOf(tag90C);
                outBal = context.substring(offset, endset);
            } else {
                outBal = context.substring(offset);
            }
            startIndex = indexLength(outBal.replace(",", "").trim());
            outBal = outBal.substring(startIndex + 1).replaceAll(",", ".")
                    .replaceAll("\r", "").replaceAll("\n", "");
            outBal = amtCheck(outBal);
        }
        //获取入账总金额
        String inBal = "0";
        if (context.contains(tag90C)) {
            offset = context.indexOf(tag90C) + tag90C.length();
            if (context.contains(tag86)) {
                endset = context.indexOf(tag86);
                inBal = context.substring(offset, endset);
            } else {
                inBal = context.substring(offset);
            }
            startIndex = indexLength(inBal.replace(",", "").trim());
            inBal = inBal.substring(startIndex + 1).replaceAll(",", ".")
                    .replaceAll("\r", "").replaceAll("\n", "");
            inBal = amtCheck(inBal);
        }
        //获取账户币种
        offset = context.indexOf(tag34F) + tag34F.length();
        String cur = context.substring(offset, offset + 3);
        //获取余额相关信息
        String openBal = "0.00";//期初
        String closeBal = "0.00";//当前
        String availBal = "0.00";//当前可用
        //当前余额=34F节点余额+90c-90d；
        //offset = context.indexOf(tag34F) + tag34F.length();
        //endset =context.indexOf(tag13D);
        //openBal=context.substring(offset+3,endset).replace(",", ".").replace("\r","").replace("\n","");
        //openBal = amtCheck(openBal);
        //closeBal=new BigDecimal(openBal).add(new BigDecimal(inBal)).subtract(new BigDecimal(outBal)).toString();
        //closeBal = amtCheck(closeBal);
        //不存在MT942文件，说明是当天的第一个MT942，
        //期初余额=上日当前余额；当前可用余额=940上日可用余额+90c-90d
        String balFilePath = bankConfig.getValueAsString("DealedPath") + File.separator + date + File.separator
                + "MT942" + File.separator + accountNum + "_7506.txt";
        if (!FileHelper.existFile(balFilePath)) {
            Calendar calendarToday = Calendar.getInstance();
            calendarToday.setTime(Format.Date8Format.parse(date));
            calendarToday.add(Calendar.DAY_OF_MONTH, -1);
            int num = 1;//初始遍历天数
            String day = bankConfig.getValueAsString("countDay");//往前遍历天数
            String dealedFile = bankConfig.getValueAsString("DealedPath") + File.separator +
                    Format.Date8Format.format(calendarToday.getTime()) +
                    File.separator + "MT940" + File.separator + accountNum + "_7505.txt";
            while (!FileHelper.existFile(dealedFile) && num <= Integer.parseInt(StringHelper.isNullOrEmpty(day) ? "10" : day)) {
                WriteBankLogLn("账户" + accountNum + "在" + Format.Date8Format.format(calendarToday.getTime()) + "日期的MT940文件不存在,继续往前一天遍历，第" + num + "次");
                calendarToday.add(Calendar.DAY_OF_MONTH, -1);
                dealedFile = bankConfig.getValueAsString("DealedPath") + File.separator +
                        Format.Date8Format.format(calendarToday.getTime()) +
                        File.separator + "MT940" + File.separator + accountNum + "_7505.txt";
                num++;
            }
            //读取文件内容
            String balContent = FileHelper.readFileText(dealedFile, charset);
            WriteBankLogLn("收到一笔新的MT942文件，开始读取940文件" + dealedFile + "内容：" + balContent);
            if (StringHelper.hasAnyChar(balContent)) {//存在MT940
                String[] bal = balContent.split("\\|");
                if (bal.length > 3) {
                    //期初余额
                    openBal = bal[2];
                    //当前余额
                    closeBal = new BigDecimal(openBal).add(new BigDecimal(inBal)).subtract(new BigDecimal(outBal)).toString();
                    //当前可用余额
                    availBal = new BigDecimal(bal[3]).add(new BigDecimal(inBal)).subtract(new BigDecimal(outBal)).toString();
                    WriteBankLogLn("存在940文件内容，计算获得：期初余额" + openBal + "，当前余额" + closeBal + "，当前可用余额" + availBal);
                }
            } else {//不存在MT940文件
                WriteBankLogLn("没有读取到940文件，账户" + accountNum + "为一个新账户");
                map.put("new", "1");//表示新账户
                //期初余额
                    /*offset = context.indexOf(tag34F) + tag34F.length();
                    endset =context.indexOf(tag13D);
                    openBal=context.substring(offset+3,endset).replace(",", ".").replace("\r","").replace("\n","");
                    openBal = amtCheck(openBal);*/
                //当前余额 期初余额+90c-90d
                //closeBal=new BigDecimal(openBal).add(new BigDecimal(inBal)).subtract(new BigDecimal(outBal)).toString();
                //closeBal = amtCheck(closeBal);
                //当前可用
                //availBal=closeBal;
            }
        } else {
            //读取文件内容：存在MT942文件 可用余额=上一次可用余额+90c-90d
            String balContent = FileHelper.readFileText(balFilePath, charset);
            WriteBankLogLn("收到一笔MT942文件，开始读取上一笔942文件" + balFilePath + "内容：" + balContent);
            if (StringHelper.hasAnyChar(balContent)) {
                String[] bal = balContent.split("\\|");
                //新账户余额全部显示0.00
                if (bal[4].equals(bal[3]) && bal[4].equals(bal[2]) && bal[4].equals("0.00")) {
                    WriteBankLogLn("账户" + accountNum + "当前余额、当前可用余额、期初余额均为0.00，默认为新增账户");
                    openBal = "0.00";
                    closeBal = "0.00";
                    availBal = "0.00";
                    map.put("new", "1");
                } else {
                    if (bal.length > 4) {
                        //期初余额
                        openBal = bal[4];
                        //当前余额
                        closeBal = new BigDecimal(bal[2]).add(new BigDecimal(inBal)).subtract(new BigDecimal(outBal)).toString();
                        //当前可用余额
                        availBal = new BigDecimal(bal[3]).add(new BigDecimal(inBal)).subtract(new BigDecimal(outBal)).toString();
                        WriteBankLogLn("根据前一MT942文件，计算获得：期初余额" + openBal + "，当前余额" + closeBal + "，当前可用余额" + availBal);
                    }
                }
            }
        }
        //计算该账户上一次的当前余额：当前余额-入账+出账
        BigDecimal bigDecimal = new BigDecimal(closeBal);
        String lastBal = bigDecimal.add(new BigDecimal(outBal)).subtract(new BigDecimal(inBal)).toString();
        //返回
        map.put("closeBal", closeBal);
        map.put("availBal", availBal);
        map.put("openBal", openBal);
        map.put("lastBal", lastBal);
        if (!StringHelper.hasAnyChar(map.get("new"))) {
            map.put("new", "0");
        }
        return map;
    }

    /**
     * 遍历字符串最后一个字母出现的位置
     *
     * @param str 字符串
     * @return
     */
    protected int indexLength(String str) {
        char[] array = str.toCharArray();
        int indexLength = 0;
        for (int i = array.length - 1; i > 0; i--) {
            if (array[i] > 'a' && array[i] < 'z' || array[i] > 'A' && array[i] < 'Z') {
                indexLength = i;
                break;
            }
        }
        return indexLength;
    }

    /**
     * 上传付款信息到ftp/sftp服务器：加密请求的文件格式均为无后缀
     *
     * @param reqString   请求报文串
     * @param payFilePath 付款文件地址
     * @param charset     编码
     * @param serverName  sftp服务器名
     * @param pubKeyId    银行公钥id
     * @param priKeyId    企业公钥id
     * @param passphrase  企业私钥密码
     * @return
     * @throws Exception
     */
    public String[] uploadPayFile(String reqString, String payFilePath, String charset, String serverName, String pubKeyId, String priKeyId, String passphrase) {
        String[] result = new String[]{"", ""};
        try {
            //请求报文reqString写入文件payFilePath
            if (exportContentToFile(reqString, payFilePath, charset)) {
                //加密请求报文
                String encryFilePath = payFilePath.replace(".txt", "");
                if (GPGUtil.encrypAndSignCmdRun(payFilePath, encryFilePath, pubKeyId, priKeyId, passphrase)) {
                    //if(GPGUtil.pgpEncryptSigned(payFilePath,encryFilePath,charset)){
                    WriteBankLogLn("加密文件成功");
                    //上传文件到ftp/sftp
                    if (uploadFile(encryFilePath, serverName)) {
                        result[0] = "ACCP";
                        result[1] = "上传成功";
                    } else {
                        result[1] = "上传失败";
                        result[0] = "ERRO";
                    }
                } else {
                    result[0] = "ERRO";
                    result[1] = "加密文件失败";
                }
            } else {
                result[0] = "ERRO";
                result[1] = "写入文件失败";
            }
        } catch (Exception e) {
            result[0] = "ERRO";
            result[1] = "上传发生异常";
        }
        return result;
    }

    /**
     * 上传付款信息到ftp/sftp服务器
     *
     * @param reqString   请求报文串
     * @param payFilePath 付款文件地址
     * @param charset     编码
     * @param serverName  sftp服务器名
     * @return
     * @throws Exception
     */
    public String[] uploadPayFile(String reqString, String payFilePath, String charset, String serverName) {
        String[] result = new String[]{"", ""};
        try {
            //请求报文reqString写入文件payFilePath
            if (exportContentToFile(reqString, payFilePath, charset)) {
                //上传文件到ftp/sftp
                if (uploadFile(payFilePath, serverName)) {
                    result[0] = "ACCP";
                    result[1] = "上传成功";
                } else {
                    result[0] = "ERRO";
                    result[1] = "上传失败";
                }
            } else {
                result[0] = "ERRO";
                result[1] = "写入文件失败";
            }
        } catch (Exception e) {
            result[0] = "ERRO";
            result[1] = "上传发生异常";
        }
        return result;
    }

    /**
     * 文件移动
     *
     * @param source 原地址
     * @param target 新地址
     * @return
     */
    public boolean renameTo(String source, String target) {
        File sourceFile = new File(target);
        if (sourceFile.exists()) {
            WriteBankLogLn("文件：" + target + "已存在，开始删除");
            if (sourceFile.delete()) {
                WriteBankLogLn("文件" + target + "删除成功");
            } else {
                WriteBankLogLn("文件：" + target + "删除失败");
                return false;
            }
        }
        boolean flag = new File(source).renameTo(new File(target));
        if (flag) {
            WriteBankLogLn("文件：" + source + " ---移动至---\r\n" + target + "  成功");
        } else {
            WriteBankLogLn("文件：" + source + " ---移动至---\r\n" + target + "  失败");
        }
        return flag;
    }

    /**
     * 打印日志
     *
     * @param strlog
     */
    public void WriteBankLogLn(String strlog) {
        sblog.append(Format.DateTimeSSSFormat.format(new Date()) + " " + strlog + "\r\n");
    }

    /**
     * 标识字段转换
     *
     * @param context 内容
     * @param flag1   标识字段1
     * @param flag2   标识字段2
     * @return
     */
    public String presenceFlag(String context, String flag1, String flag2) {
        String flag = "";
        if (StringHelper.hasAnyChar(context)) {
            if (context.contains(flag1)) {
                flag = flag1;
            } else if (context.contains(flag2)) {
                flag = flag2;
            }
        }
        return flag;
    }

    public String amtCheck(String amt) {
        if (amt.startsWith(".")) {
            amt = "0" + amt;
        }
        if (amt.endsWith(".")) {
            amt = amt + "00";
        }
        amt = keepTwoDecimals(amt);
        return amt;
    }

    /**
     * 去掉小数点后两位的任何元素
     *
     * @param amt
     * @return
     */
    public String keepTwoDecimals(String amt) {
        if (amt.indexOf(".") + 3 < amt.length()) {
            amt = amt.substring(0, amt.indexOf(".") + 3);
        }
        return amt;
    }

    /**
     * 判断是否为英文字母
     *
     * @param character 字符
     * @return
     */
    public static boolean isLetter(char character) {
        if (((character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z'))) {
            return true;
        }
        return false;
    }

    /**
     * 写入文件内容
     *
     * @param content
     * @param fullName
     * @param charset
     * @return
     */
    public boolean exportContentToFile(String content, String fullName, String charset) {
        if (StringHelper.isNullOrEmpty(content) || StringHelper.isNullOrEmpty(fullName)) {
            return false;
        }
        try {
            FileHelper.writeFile(fullName, content, charset);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return FileHelper.existFile(fullName);
    }

    /**
     * 上传文件到sftp
     *
     * @param fullName
     * @return
     * @throws IOException
     */
    public boolean uploadFile(String fullName, String ftpName) throws IOException {
        FtpSet ftpSet = bankFront.getFtpSet(ftpName);
        ftpSet.downDir = StringHelper.trimEndFileSp(ftpSet.downDir) + SEPARATOR;
        ftpSet.upDir = StringHelper.trimEndFileSp(ftpSet.upDir) + SEPARATOR;
        String upDir = ftpSet.upDir;
        File file = new File(fullName);
        String filename = upDir + file.getName();
        FileInputStream inputStream = null;
        SftpPortClient sftpPortClient = null;
        try {
            sftpPortClient = new SftpPortClient(ftpSet);
            String sftpType = bankConfig.getValueAsString("sftpType");
            String sshKeyPassword = bankConfig.getValueAsString("privateKeyPaswd");
            sshKeyPassword = StringHelper.hasAnyChar(sshKeyPassword) ? sshKeyPassword : ftpSet.sshKeyPassword;
            switch (Integer.parseInt(sftpType)) {
                //登录名和私钥
                case 2:
                    sftpPortClient.connectBySSH();
                    break;
                //登录名和私钥和私钥密码
                case 3:
                    sftpPortClient.connectBySSHPrvkey(sshKeyPassword);
                    break;
                //登录名和登录密码和私钥和私钥密码
                case 4:
                    sftpPortClient.connectBySSHPrvkeyAndPsd(sshKeyPassword);
                    break;
                default:
                    WriteBankLogLn("配置暂不支持");
            }
            inputStream = new FileInputStream(file);
            FtpReceiver receiver = sftpPortClient.uploadFile("", inputStream, filename);
            if (receiver.isCompleted) {
                WriteBankLogLn("上传文件：" + filename + "成功");
            } else {
                WriteBankLogLn("上传文件：" + filename + "失败");
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            WriteBankLogLn("上传文件失败：" + e);
            return false;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            sftpPortClient.disconnect();
        }
        return true;
    }

    /**
     * 获取支付状态
     *
     * @param p_ReqSeqID
     * @param payDate
     * @return
     */
    public String[] getPayStatus(String p_ReqSeqID, Date payDate) {
        WriteBankLogLn("======开始获取付款状态，流水号为：" + p_ReqSeqID + "，交易日期为" + payDate + "======");
        String[] result = new String[]{"", ""};//状态码
        try {
            //当前日期
            Date date = new Date();
            Calendar calendarToDay = Calendar.getInstance();
            calendarToDay.setTime(date);
            //交易日期
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(payDate);
            String getAck = trimEndFileSp(bankConfig.getValueAsString("DealedPath")) + File.separator
                    + Format.Date8Format.format(calendar.getTime()) + File.separator + "ACK";//ACK文件路径
            String getMTPath = trimEndFileSp(bankConfig.getValueAsString("DealedPath")) + File.separator
                    + Format.Date8Format.format(calendar.getTime()) + File.separator + "MT940";//MT文件路径
            String getMT942Path = trimEndFileSp(bankConfig.getValueAsString("DealedPath")) + File.separator
                    + Format.Date8Format.format(calendar.getTime()) + File.separator + "MT942";//MT文件路径
            while (Integer.parseInt(Format.Date8Format.format(calendar.getTime())) <= Integer.parseInt(Format.Date8Format.format(calendarToDay.getTime()))) {
                //1、先遍历解析后的mt940文件
                WriteBankLogLn("======遍历940文件start：" + getMTPath + "流水号【" + p_ReqSeqID + "】======");
                File mt940Files = new File(getMTPath);
                if (mt940Files.listFiles() != null) {
                    //遍历所有的7516文件
                    for (File file : mt940Files.listFiles()) {
                        if (file.getName().contains("_7516.txt")) {
                            WriteBankLogLn("遍历940文件：" + getMTPath + File.separator + file.getName());
                            boolean flag = fileIsExist(file, p_ReqSeqID);
                            if (flag) {
                                WriteBankLogLn("确认文件：" + file.getPath() + "内容为：" + FileHelper.readFileText(file.getPath(), charset));
                                result[0] = "A40";
                                result[1] = "对账单确认成功";
                                return result;
                            }
                        }
                    }
                }
                //2、遍历解析后的mt942文件
                WriteBankLogLn("======遍历942文件start：" + getMTPath + "流水号【" + p_ReqSeqID + "】======");
                File mt942Files = new File(getMT942Path);
                if (mt942Files.listFiles() != null) {
                    //遍历所有的7515文件
                    for (File file : mt942Files.listFiles()) {
                        if (file.getName().contains("_7515.txt")) {
                            WriteBankLogLn("遍历942文件：" + mt942Files + File.separator + file.getName());
                            boolean flag = fileIsExist(file, p_ReqSeqID);
                            if (flag) {
                                WriteBankLogLn("确认文件：" + file.getPath() + "内容为：" + FileHelper.readFileText(file.getPath(), charset));
                                result[0] = "A40";
                                result[1] = "对账单确认成功";
                                return result;
                            }
                        }
                    }
                }
                //3、再遍历解析后的ack文件
                String ackPath = getAck + File.separator + p_ReqSeqID;
                WriteBankLogLn("======mt文件未找到流水【" + p_ReqSeqID + "】，开始遍历ack文件：" + ackPath + "======");
                if (FileHelper.existFile(ackPath)) {
                    WriteBankLogLn("ACK文件夹【" + ackPath + "】存在，开始获取状态");
                    //取当前最后的ack文件
                    String ackStatuFile = "";
                    if (FileHelper.existFile(ackPath + File.separator + p_ReqSeqID + "_3.txt")) {
                        ackStatuFile = ackPath + File.separator + p_ReqSeqID + "_3.txt";
                    } else if (FileHelper.existFile(ackPath + File.separator + p_ReqSeqID + "_2.txt")) {
                        ackStatuFile = ackPath + File.separator + p_ReqSeqID + "_2.txt";
                    } else {
                        ackStatuFile = ackPath + File.separator + p_ReqSeqID + "_1.txt";
                    }
                    //从ack文件中读取状态
                    if (FileHelper.existFile(ackStatuFile)) {
                        WriteBankLogLn("存在ack文件" + ackStatuFile);
                        String content = FileHelper.readFileText(ackStatuFile, charset);
                        if (StringHelper.hasAnyChar(content)) {
                            String[] status = content.split("\\|");
                            if (status[0].equals(p_ReqSeqID) && status.length == 3) {
                                String rspCode = status[1];
                                WriteBankLogLn("获取Lv状态为" + status[2]);
                                //处理中状态码
                                String payStatusI4101 = bankConfig.getValueAsString("payStatusI4101");
                                String I4101 = StringHelper.hasAnyChar(payStatusI4101) ? payStatusI4101 : "ACCP";
                                //处理失败状态码
                                String payStatusE8001 = bankConfig.getValueAsString("payStatusE8001");
                                String E8001 = StringHelper.hasAnyChar(payStatusE8001) ? payStatusE8001 : "RJCT";
                                if (I4101.contains(rspCode)) {
                                    result[0] = "A25";
                                    result[1] = "指令正在处理：" + status[2];
                                } else if (E8001.contains(rspCode)) {
                                    result[0] = "A90";
                                    result[1] = "文件被拒绝：" + status[2];
                                    return result;
                                }
                            }
                        }
                    }
                }
                //4 遍历MT文件流水不存在，则开始遍历交易日期后一天
                if (Integer.parseInt(Format.Date8Format.format(calendar.getTime())) < Integer.parseInt(Format.Date8Format.format(calendarToDay.getTime()))) {
                    WriteBankLogLn("======在" + File.separator + Format.Date8Format.format(calendar.getTime()) + "日期的MT文件不存在,往后一天遍历======");
                } else {
                    WriteBankLogLn("======在" + File.separator + Format.Date8Format.format(calendar.getTime()) + "日期的MT文件不存在,银行未返回明细流水======");
                }
                calendar.add(Calendar.DAY_OF_MONTH, +1);
                getAck = trimEndFileSp(bankConfig.getValueAsString("DealedPath")) + File.separator + Format.Date8Format.format(calendar.getTime()) + File.separator + "ACK";//ACK文件路径
                getMTPath = trimEndFileSp(bankConfig.getValueAsString("DealedPath")) + File.separator + Format.Date8Format.format(calendar.getTime()) + File.separator + "MT940";//MT文件路径
                getMT942Path = trimEndFileSp(bankConfig.getValueAsString("DealedPath")) + File.separator + Format.Date8Format.format(calendar.getTime()) + File.separator + "MT942";//MT文件路径
            }
        } catch (Exception e) {
            e.printStackTrace();
            result[0] = "A10";
            result[1] = "银行未返回指令状态";
            WriteBankLogLn("获取ack文件或mt文件中的支付状态失败：" + e.getMessage());
        }
        if ("".equals(result[0])) {
            result[0] = "A10";
            result[1] = "银行未返回指令状态";
        }
        return result;
    }

    /**
     * 校验字符串是否存在文件中
     *
     * @param file：文件路径
     * @param p_ReqSeqID：字符串
     * @return
     */
    protected boolean fileIsExist(File file, String p_ReqSeqID) throws Exception {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            String sLine = "";
            while ((sLine = br.readLine()) != null) {
                if (sLine.contains(p_ReqSeqID)) {//MT文件存在该笔流水，交易成功
                    return true;
                }
            }
        } catch (Exception e) {
            return false;
        } finally {
            if (br != null) {
                br.close();
            }
        }
        return false;
    }

    /**
     * 解密文件
     *
     * @param receivePath 加密文件目录
     * @param decryptPath 解密后的文件目录
     * @param successPath 解密成功后的加密文件目录
     */
    public void decryptFileIsGpg(String receivePath, String decryptPath, String successPath, boolean withVerify) {
        //开始解密sftp服务器下载的文件
        File file = new File(receivePath);
        if (file.listFiles().length > 0) {
            for (File file2 : file.listFiles()) {
                if (file2.isFile()) {
                    String fileContent = FileHelper.readFileText(file2.getPath(), charset);
                    if ("false".equals(bankConfig.getValueAsString("TransResult"))) {
                        //不需要解密文件，直接将文件移动到解密后存放的文件夹里
                        renameTo(file2.getPath(), decryptPath + file2.getName());
                    } else {
                        if (file2.getName().contains(".pgp") || (!fileContent.contains(tag20) && !fileContent.contains("Document"))) {
                            //需要解密，进行解密
                            StringBuilder decryptFile = new StringBuilder(decryptPath);
                            if (file2.getName().contains(".pgp")) {
                                decryptFile.append(file2.getName().replace(".pgp", ".txt"));
                            } else if (!file2.getName().contains(".txt")) {
                                decryptFile.append(file2.getName()).append(".txt");
                            } else {
                                decryptFile.append(file2.getName());
                            }
                            //表示文件已经解析
                            if (withVerify) {
                                GPGUtil.pgpDecryptAndVerify(bankConfig.getValueAsString("bankPubPath"), bankConfig.getValueAsString("orgPrvPath")
                                        , bankConfig.getValueAsString("orgPrvPassWord").toCharArray(), file2.getPath(), decryptFile.toString(), charset);
                            } else {
                                GPGUtil.pgpDecryptWithoutVerify(bankConfig.getValueAsString("orgPrvPath")
                                        , bankConfig.getValueAsString("orgPrvPassWord").toCharArray(), file2.getPath(), decryptFile.toString(), charset);
                            }

                            //处理文件
                            if (FileHelper.existFile(decryptFile.toString())) {
                                WriteBankLogLn(file2.getName() + "解密报文成功");
                                String successFilePath = StringHelper.trimEndFileSp(successPath) + File.separator + Format.Date8Format.format(new Date()) + File.separator;
                                if (!FileHelper.existFile(successFilePath)) {
                                    FileHelper.mkdir(successFilePath);
                                }
                                boolean flag = new File(file2.getPath()).renameTo(new File(successFilePath + file2.getName()));
                                if (flag) {
                                    WriteBankLogLn("文件：" + file2.getPath() + " ---移动至---\r\n" + successFilePath + file2.getName() + "  成功");
                                } else {
                                    WriteBankLogLn("文件：" + file2.getPath() + " ---移动至---\r\n" + successFilePath + file2.getName() + "  失败");
                                    if (FileHelper.deleteFileIfExists(file2.getPath())) {
                                        WriteBankLogLn("删除此文件成功");
                                    }
                                }
                            }
                        } else {
                            //不需要解密文件，直接将文件移动到解密后存放的文件夹里
                            renameTo(file2.getPath(), decryptPath + file2.getName());
                        }
                    }
                }
            }
        }
    }

    /**
     * 文件加密加签上传
     *
     * @param reqString   请求报文串
     * @param payFilePath 付款文件地址
     * @param charset     编码
     * @param serverName  sftp服务器名
     * @return
     * @throws Exception
     */
    public String[] uploadPayFileIsEncrypt(String reqString, String payFilePath, String charset, String serverName) {
        String[] result = new String[]{"", ""};
        try {
            //请求报文reqString写入文件payFilePath
            if (exportContentToFile(reqString, payFilePath, charset)) {
                //加密请求报文
                String encryFilePath = payFilePath.replace(".txt", "");
                if (GPGUtil.pgpEncryptSigned(bankConfig.getValueAsString("bankPubPath"), bankConfig.getValueAsString("orgPrvPath")
                        , bankConfig.getValueAsString("orgPrvPassWord").toCharArray(), payFilePath, encryFilePath, charset)) {
                    WriteBankLogLn("加密文件成功");
                    //上传文件到ftp/sftp
                    if (uploadFile(encryFilePath, serverName)) {
                        result[0] = "ACCP";
                        result[1] = "上传成功";
                    } else {
                        result[1] = "上传失败";
                        result[0] = "ERRO";
                    }
                } else {
                    result[0] = "ERRO";
                    result[1] = "加密文件失败";
                }
            } else {
                result[0] = "ERRO";
                result[1] = "写入文件失败";
            }
        } catch (Exception e) {
            result[0] = "ERRO";
            result[1] = "上传发生异常";
        }
        return result;
    }
}